home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume3 / awm2 / part01 next >
Encoding:
Internet Message Format  |  1989-02-17  |  54.3 KB

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v03i017:  Ardent Window Manager, Patchlevel 9, Part01/12
  5. Message-ID: <2067@wyse.wyse.com>
  6. Date: 17 Feb 89 19:15:38 GMT
  7. Organization: Wyse Technology, San Jose
  8. Lines: 1800
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: kmw@ardent (Ken Wallich)
  12. Posting-number: Volume 3, Issue 17
  13. Archive-name: awm2/part01
  14.  
  15. [Due to the size of the diffs and the fact that there are at least
  16. 2 widely distributed version out there, I am including the complete
  17. sources and not just a patch. -mcw]
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 1 (of 12)."
  26. # Contents:  README awm.c bitmaps bitmaps/twm.gray.bm menus
  27. # Wrapped by mikew@wyse on Fri Feb 17 10:50:19 1989
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'README' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'README'\"
  31. else
  32. echo shar: Extracting \"'README'\" \(7615 characters\)
  33. sed "s/^X//" >'README' <<'END_OF_FILE'
  34. XThis file last changed February 8th, 1989.
  35. X
  36. XIn the grand tradition of adding to the README file, rather than
  37. Xjust starting it from scratch...
  38. X
  39. XThis represents the 2nd netwide release of awm. A number of bugs in
  40. Xthe menu package have been fixed (though by no means all) and awm
  41. Xshould work much better on color systems. The code has been more
  42. Xextensively linted and generally cleaned up. Several new bits of
  43. Xknowledge have made it possible to speed up things quite a bit in
  44. Xcertain situations. Subjective analysis is encouraged.
  45. XMany many niggling little problems have been fixed, though nothing
  46. Xsubstantial has been changed or added. It was felt that increasing
  47. Xthe reliability of awm was far more important than adding new features,
  48. Xthough many are planned. Awm should now be a good deal more portable,
  49. Xif you get any warnings (under BSD or SYSV) during compilation, let us
  50. Xknow.
  51. X
  52. XAs usual, people are encouraged to send mail to: awm-bugs@ardent.ardent.com
  53. Xor to the author:
  54. X
  55. X                Jordan Hubbard
  56. X                                PCS Computer Systeme GmbH
  57. X                                Pfaelzer-Wald-Str. 36
  58. X                                D-8000 Muenchen 90.
  59. X                                West Germany
  60. X                uunet!pyramid!pcsbst!jkh
  61. X
  62. X-------
  63. XOld README follows:
  64. X
  65. XThis represents the first real release of the Ardent Window Manager (awm).
  66. XIt's being released on the same terms as its predecessor (uwm) with
  67. Xone additional request: Since this window manager is the "official"
  68. Xwindow manager of Ardent Computer, a lot more effort and time will
  69. Xbe expended to ensure that it works reliably. Please try and coordinate
  70. Xfixes and enhancements through Ardent so that all may benefit. There
  71. Xare sure to be some bugs, we'll be here trying to fix them. Send
  72. Xbug reports to the author, or to:
  73. X
  74. X    {decwrl, uunet, hplabs, ucbcad, dlb}!ardent!awm-bugs
  75. X
  76. X
  77. XINSTALLATION:
  78. X
  79. XInstallation should be fairly straightforward. If you're using imake,
  80. Xfirst modify $(TOPDIR)/util/imake.includes/Imake.tmpl to define a macro
  81. Xcalled AWMDIR (look at UWMDIR for an example) which should point to
  82. Xsomeplace where you want to stash the system.awmrc file. If you like,
  83. Xyou can just make UWMDIR and AWMDIR point to the same place since uwm
  84. Xand awm's file names are different and won't conflict with eachother. If
  85. Xyou're using make (and don't want to use imake), modify the definition
  86. Xof AWMDIR in the Makefile instead (sort of the wrong way to do it though).
  87. X
  88. XCertain compilers don't like the #ident lines we use for sccs. If yours
  89. Xdoesn't, do a
  90. X
  91. X    make noident
  92. X
  93. XIn the awm directory to remove all #ident lines from the source code.
  94. X
  95. XThe usual differences between system V and BSD include file structures
  96. Xmay also cause you trouble. In particular, <sys/time.h> may be different.
  97. XIf FocusChng.c doesn't compile correctly on your system, see if the
  98. Xcorrect include file is in /usr/include or /usr/include/sys (the correct
  99. Xone should define a timeval struct). I've also heard that SunOS 4.0
  100. Xfails to compile code that compiles fine on SunOS 3.x. I don't know
  101. Xwhat the symptoms are (since I don't have a 4.0 system around), but
  102. XI've heard that the fix is to include <sys/file.h> in exp_path.c and
  103. Xawm.c.
  104. X
  105. XIf you want awm's output to go to the console device (assumed to be
  106. X/dev/console), define CONSOLE in the I/Makefile (there are appropriate
  107. Xcomments that will show you what to do).
  108. X
  109. XIf all this seems confusing, send me mail and I'll try to explain
  110. Xit differently.
  111. X
  112. XSupport for the RTL Neaten package has been added. If you'd like to compile
  113. Xit in, you need to do two things:
  114. X
  115. X  1. Obtain the RTL neaten package somehow. It's too big to bundle with awm,
  116. X     so it's expected that you'll have obtained it by some other means.
  117. X     If you are on a system V system with 14 character file names,
  118. X     you're in for a bit for work. Many of the files in the neaten
  119. X     package have very long names. After you've renamed all of the > 14 char
  120. X     files, you'll want to modify Makefile.rtl (in the awm directory)
  121. X     identically so that the file names match the new ones you've chosen.
  122. X
  123. X  2. The makefile that comes with the neaten package assumes that you want to
  124. X     compile their neatening window manager (nuwm), so you don't want to use
  125. X     that. Awm will automatically use the "Makefile.rtl" makefile to compile
  126. X     the neaten package (see below), as long as it knows where you've put it.
  127. X     Modify awm's Imakefile (or Makefile) to point to the directory
  128. X     where neaten resides (the macro NEATEN_LIB) and uncomment/comment the
  129. X     appropriate macro definition lines.
  130. X
  131. X  3. Do an imake/make. The make will compile all of awm's files and then
  132. X     proceed to make a neaten.a (in the neaten directory) to link against.
  133. X
  134. X
  135. X   If you don't compile awm with Neaten, the function f.neaten can
  136. X   still be bound but it will just print a warning message if invoked.
  137. X
  138. X   Please note that the Neaten package has not been extensively tested with
  139. X   awm and should be considered an experimental "frill" more than anything else.
  140. X   It seems to shuffle icons around ok, though I don't understand some of its
  141. X   window placement logic. If it's useful, use it, if not, don't compile it in.
  142. X
  143. X
  144. XThe rtl menu package in menus (non-optional) has its own Makefile which
  145. Xyou may wish to customize (compiler flags, compiler type, etc), though
  146. Xthe default configuration should produce a working awm binary on your
  147. Xsystem. This whole setup needs to be gone through and redone, but that will
  148. Xhave to wait for another day (or a kind volunteer).
  149. X
  150. X
  151. XFirst time users of awm will probably want to read the manual page carefully
  152. Xand then set about tailoring their .Xdefaults file accordingly. The actual
  153. Xformat of the .awmrc file does not differ substantially from uwm's .uwmrc file,
  154. Xbut since much of the variable declaration stuff has been moved into .Xdefaults,
  155. Xa .uwmrc file will fail miserably if blithly copied into a .awmrc file. It's
  156. Xprobably easier to go from scratch, starting with .Xdefaults.
  157. X
  158. XAfter defaults have been entered (by far the largest task), a careful
  159. Xexamination of your current uwm interface should be done to see what possible
  160. Xbenefits might be derived from title bar, gadget and border contexts.
  161. XYou will most likely be able to eliminate almost all "chorded" buttons and
  162. Xgo to naked buttons on title bars/gadgets/borders. You can now also bind
  163. Xnaked buttons to icons without having the button stolen from applications,
  164. Xso it's usually a win to bind an f.iconify to the icon context if you like the
  165. Xway X10's xterm used to work.
  166. X
  167. XHighlighting is a new feature which does quite a bit more than just tweak
  168. Xborder colors. It will change the title bar text font (and redisplay the text)
  169. Xas well as alternating between two different title bar background pixmaps and
  170. Xor border context pixmaps.
  171. X
  172. XI use a blank pixmap for the regular background (which is the default, I.E.
  173. XI don't declare one) and a pixmap containing 7 horizontal lines for the
  174. XBoldPixmap.  The effect is not unlike a macintosh window. With some careful
  175. Xartistry (and placement) of gadget boxes, one could probably emulate this
  176. Xeven more closely, though I'm not sure why one would want to.
  177. X
  178. XWhen creating gadget box pixmaps, it's suggested that you look at the cursor
  179. Xfont first as there are a lot of suitable glyphs already there.
  180. X
  181. X
  182. XAny and all suggestions are, of course, appreciated. In addition to the
  183. Xawm-bugs address given previously, you may communicate with the author
  184. Xat any of the following addresses:
  185. X
  186. X
  187. X            Author:        Jordan Hubbard
  188. X            Internet:    jkh@violet.berkeley.edu
  189. X            UUCP:        {decwrl, hplabs, uunet}!ardent!jkh
  190. X            U.S. Mail:    Ardent Computer
  191. X                    880 Maude
  192. X                    Sunnyvale, Ca. 94086
  193. END_OF_FILE
  194. if test 7615 -ne `wc -c <'README'`; then
  195.     echo shar: \"'README'\" unpacked with wrong size!
  196. fi
  197. # end of 'README'
  198. fi
  199. if test -f 'awm.c' -a "${1}" != "-c" ; then 
  200.   echo shar: Will not clobber existing file \"'awm.c'\"
  201. else
  202. echo shar: Extracting \"'awm.c'\" \(43072 characters\)
  203. sed "s/^X//" >'awm.c' <<'END_OF_FILE'
  204. X
  205. X
  206. X
  207. X#ifndef lint
  208. Xstatic char *rcsid_awm_c = "$Header: /usr/graph2/X11.3/contrib/windowmgrs/awm/RCS/awm.c,v 1.3 89/02/07 22:39:57 jkh Exp $";
  209. X#endif  lint
  210. X
  211. X#include "X11/copyright.h"
  212. X/*
  213. X *
  214. X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  215. X *
  216. X * Copyright 1987 by Jordan Hubbard.
  217. X *
  218. X *
  219. X *                         All Rights Reserved
  220. X *
  221. X * Permission to use, copy, modify, and distribute this software and its
  222. X * documentation for any purpose and without fee is hereby granted,
  223. X * provided that the above copyright notice appear in all copies and that
  224. X * both that copyright notice and this permission notice appear in
  225. X * supporting documentation, and that the name of Ardent Computer
  226. X * Corporation or Jordan Hubbard not be used in advertising or publicity
  227. X * pertaining to distribution of the software without specific, written
  228. X * prior permission.
  229. X *
  230. X */
  231. X
  232. X/*
  233. X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  234. X *
  235. X *                         All Rights Reserved
  236. X *
  237. X * Permission to use, copy, modify, and distribute this software and its
  238. X * documentation for any purpose and without fee is hereby granted,
  239. X * provided that the above copyright notice appear in all copies and that
  240. X * both that copyright notice and this permission notice appear in
  241. X * supporting documentation, and that the name of Digital Equipment
  242. X * Corporation not be used in advertising or publicity pertaining to
  243. X * distribution of the software without specific, written prior permission.
  244. X *
  245. X *
  246. X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  247. X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  248. X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  249. X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  250. X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  251. X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  252. X * SOFTWARE.
  253. X */
  254. X
  255. X
  256. X/*
  257. X * MODIFICATION HISTORY
  258. X *
  259. X * 000 -- M. Gancarz, DEC Ultrix Engineering Group
  260. X * 001 -- Loretta Guarino Reid, DEC Ultrix Engineering Group,
  261. X *  Western Software Lab. Convert to X11.
  262. X * 002 -- Jordan Hubbard, U.C. Berkeley. Add title bar context stuff.
  263. X * 003 -- Jordan Hubbard, Ardent Computer. Added gadgets, border contexts.
  264. X * 1.6 -- Various irritating changes. Support for WMSTATE..
  265. X */
  266. X
  267. X#include <signal.h>
  268. X#include "awm.h"
  269. X#include <sys/ioctl.h>
  270. X#include "X11/Xutil.h"
  271. X#include "X11/cursorfont.h"
  272. X
  273. X#ifdef titan
  274. X#include <sys/file.h>
  275. X#endif
  276. X
  277. X#ifdef PCS
  278. X#include <unistd.h>
  279. X#include <bsd/sys/time.h>
  280. X#endif
  281. X#ifdef PROFIL
  282. X#include <signal.h>
  283. X/*
  284. X * Dummy handler for profiling.
  285. X */
  286. Xptrap()
  287. X{
  288. X     exit(0);
  289. X}
  290. X#endif
  291. X
  292. XBoolean NeedRootInput=FALSE;
  293. XMenuOptionsMask options;
  294. Xchar *sfilename;
  295. Xchar execfile[NAME_LEN]; /* Pointer to file to exec with -e */
  296. XBoolean Snatched;
  297. XBoolean desktop_execd = TRUE;
  298. Xextern FILE *yyin;
  299. Xextern int errorStatus;
  300. Xextern int ErrorHandler();
  301. Xextern XContext AwmContext;
  302. X
  303. X/*
  304. X * Main program.
  305. X */
  306. Xmain(argc, argv, environ)
  307. Xint argc;
  308. Xchar **argv;
  309. Xchar **environ;
  310. X{
  311. X     int hi;            /* Button event high detail. */
  312. X     int lo;            /* Button event low detail. */
  313. X     int x, y;                  /* Mouse X and Y coordinates. */
  314. X     int root_x, root_y;        /* Mouse root X and Y coordinates. */
  315. X     int cur_x, cur_y;        /* Current mouse X and Y coordinates. */
  316. X     int down_x, down_y;    /* mouse X and Y at ButtonPress. */
  317. X     int str_width;             /* Width in pixels of output string. */
  318. X     unsigned int pop_width, pop_height; /* Pop up window width and height. */
  319. X     int context;        /* Root, window, or icon context. */
  320. X     unsigned int ptrmask;    /* for QueryPointer */
  321. X     Boolean func_stat;        /* If true, function swallowed a ButtonUp. */
  322. X     Boolean delta_done;    /* If true, then delta functions are done. */
  323. X     Boolean local;        /* If true, then do not use system defaults. */
  324. X     Boolean nolocal;        /* If true, ignore user defaults */
  325. X     register Binding *bptr;    /* Pointer to Bindings list. */
  326. X     char *root_name;        /* Root window name. */
  327. X     char *display = NULL;    /* Display name pointer. */
  328. X     char message[128];        /* Error message buffer. */
  329. X     char *rc_file;        /* Pointer to $HOME/.awmrc. */
  330. X     Window event_win;          /* Event window. */
  331. X     Window root;        /* Root window for QueryPointer. */
  332. X     AwmInfoPtr awi;
  333. X     XEvent button_event;     /* Button input event. */
  334. X     XGCValues xgc;        /* to create font GCs */
  335. X     char *malloc();
  336. X     XSetWindowAttributes swa;
  337. X     unsigned long valuemask;
  338. X     Window bwin;        /* Button window */
  339. X     int num;
  340. X     
  341. X     /* next three variables are for XQueryWindow */
  342. X     Window junk;
  343. X     Window *kiddies = NULL;
  344. X     unsigned int nkids;
  345. X     
  346. X     Entry("main")
  347. X      
  348. X#ifdef PROFIL
  349. X      signal(SIGTERM, ptrap);
  350. X#endif
  351. X     
  352. X     /* 
  353. X      * Parse the command line arguments.
  354. X      */
  355. X     Argv = argv;
  356. X     Environ = environ;
  357. X     local = nolocal = FALSE;
  358. X     argc--, argv++;
  359. X     /*
  360. X      * The destruction of '-e' args below is to prevent the startup
  361. X      * command from being invoked again if we do an f.restart (see
  362. X      * Restart.c and Argv)
  363. X      */
  364. X     while (argc) {
  365. X      if (**argv == '-') {
  366. X           if (!strcmp(*argv, "-display") || !strcmp(*argv, "-d")) {
  367. X            argc--; argv++;
  368. X            if (argc <= 0)
  369. X             Usage();
  370. X            display = *argv;
  371. X           }
  372. X           else if (!(strcmp(*argv, "-f"))) {
  373. X            argc--, argv++;
  374. X            if ((argc == 0) || (Startup_File[0] != '\0'))
  375. X             Usage();
  376. X            strncpy(Startup_File, *argv, NAME_LEN);
  377. X           }
  378. X           else if (!(strcmp(*argv, "-e"))) {
  379. X            strcpy(*argv, "--");    /* destroy the arg */
  380. X            argc--; argv++;
  381. X            if ((argc == 0) || (execfile[0] != '\0'))
  382. X             Usage();
  383. X            desktop_execd = FALSE; /* assume we have desktop to run */
  384. X            strncpy(execfile, *argv, NAME_LEN);
  385. X           }
  386. X           /* Destroyed arg, skip over what used to be filename for -e */
  387. X           else if (!(strcmp(*argv, "--"))) {
  388. X            argv += 2; argc -= 2;
  389. X            continue;
  390. X           }
  391. X           else if (!(strcmp(*argv, "-b")))
  392. X            local = TRUE;
  393. X           else if (!(strcmp(*argv, "-i")))
  394. X            nolocal = TRUE;
  395. X           
  396. X           else Usage();
  397. X      }
  398. X      else
  399. X           Usage();
  400. X      argc--, argv++;
  401. X     }
  402. X#ifdef CONSOLE
  403. X     if (access("/dev/console", W_OK) == 0) {
  404. X          freopen("/dev/console", "w", stderr);
  405. X      freopen("/dev/console", "w", stdout);
  406. X     }
  407. X#endif /* CONSOLE */
  408. X     /* Open the damn display */
  409. X     if ((dpy = XOpenDisplay(display)) == NULL) {
  410. X      fprintf(stderr, "awm: Unable to open display\n");
  411. X      exit(1);
  412. X     }
  413. X
  414. X     scr = DefaultScreen(dpy);
  415. X     
  416. X     /*
  417. X      * Set XErrorFunction to be non-terminating.
  418. X      */
  419. X     XSetErrorHandler(ErrorHandler);
  420. X     
  421. X     /*
  422. X      * Force child processes to disinherit the TCP file descriptor.
  423. X      * This helps shell commands forked and exec'ed from menus
  424. X      * to work properly. God knows if this works under SysV.
  425. X      */
  426. X     if ((status = fcntl(ConnectionNumber(dpy), F_SETFD, 1)) == -1) {
  427. X      perror("awm: child cannot disinherit TCP fd");
  428. X      Error("TCP file descriptor problems");
  429. X     }
  430. X     
  431. X     /*
  432. X      * Initialize the menus for later use.
  433. X      */
  434. X     RTLMenu_Option_Set(options, rightoffset);
  435. X     RTLMenu_Initialize(options);
  436. X     
  437. X     /* Init the context manager stuff */
  438. X     AwmContext = XUniqueContext();
  439. X     
  440. X     /*
  441. X      * Get all the defaults we expect from the resource manager.
  442. X      */
  443. X     FocusSetByUser = FALSE;
  444. X     Get_Defaults();
  445. X#if defined(WMSTATE)
  446. X     wm_state_atom = XInternAtom(dpy, "WM_STATE", False);
  447. X#endif /* WMSTATE */
  448. X
  449. X     /*
  450. X      * Initialize the default bindings.
  451. X      */
  452. X     if (!local)
  453. X      InitBindings();
  454. X     
  455. X     /*
  456. X      * Read in and parse $HOME/.awmrc, if it exists.
  457. X      */
  458. X     if (!nolocal) {
  459. X      extern char *getenv();
  460. X      char *home = getenv("HOME");
  461. X      if( !home )
  462. X          Error( "Cannot find home" );
  463. X      sfilename = rc_file = malloc(NAME_LEN);
  464. X      sprintf(rc_file, "%s/.awmrc", home);
  465. X      if ((yyin = fopen(rc_file, "r")) != NULL) {
  466. X           Lineno = 1;
  467. X           yyparse();
  468. X           fclose(yyin);
  469. X           if (Startup_File_Error)
  470. X            Error("Bad .awmrc file...aborting");
  471. X      }
  472. X     }
  473. X     /* 
  474. X      * Read in and parse the startup file from the command line, if
  475. X      * specified.
  476. X      */
  477. X     if (Startup_File[0] != '\0') {
  478. X      sfilename = Startup_File;
  479. X      if ((yyin = fopen(Startup_File, "r")) == NULL) {
  480. X           sprintf(message, "Cannot open startup file '%s'", Startup_File);
  481. X           Error(message);
  482. X      }
  483. X      Lineno = 1;
  484. X      yyparse();
  485. X      fclose(yyin);
  486. X      if (Startup_File_Error)
  487. X           Error("Bad startup file...aborting");
  488. X     }
  489. X
  490. X     if (Startup_File_Error)
  491. X      Error("Bad startup file...aborting");
  492. X
  493. X     /*
  494. X      * Catch some of the basic signals so we don't get rudely killed without
  495. X      * cleaning up first.
  496. X      */
  497. X#ifdef titan
  498. X          signal(SIGHUP, Quit);
  499. X     signal(SIGTERM, Quit);
  500. X     signal(SIGQUIT, Quit);
  501. X     signal(SIGINT, Quit);
  502. X
  503. X     /* ignore SIGTTOU */
  504. X
  505. X     signal(SIGTTOU, SIG_IGN);
  506. X#else
  507. X
  508. X     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
  509. X      signal(SIGHUP, Quit);
  510. X     if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  511. X      signal(SIGTERM, Quit);
  512. X     if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
  513. X      signal(SIGTERM, Quit);
  514. X     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  515. X      signal(SIGINT, Quit);
  516. X#endif
  517. X
  518. X     /*
  519. X      * If the root window has not been named, name it.
  520. X      */
  521. X     status = XFetchName(dpy, RootWindow(dpy, scr), &root_name);
  522. X     if (root_name == NULL) 
  523. X      XStoreName(dpy, RootWindow(dpy, scr), " X Root Window ");
  524. X     else
  525. X      XFree(root_name);
  526. X     /* register the root window */
  527. X     RegisterWindow(RootWindow(dpy, scr));
  528. X
  529. X     ScreenHeight = DisplayHeight(dpy, scr);
  530. X     ScreenWidth = DisplayWidth(dpy, scr);
  531. X
  532. X     /*
  533. X      * Create the menus. This function also sticks the RTL menu "handle"
  534. X      * into the appropriate binding after it's been created and initialized.
  535. X      */
  536. X     Create_Menus();
  537. X
  538. X     /*
  539. X      * check the gadgets.
  540. X      */
  541. X     if (CheckGadgets())
  542. X      Error("Error in gadget declarations. Exiting...\n");
  543. X
  544. X     /*
  545. X      * Store all the cursors.
  546. X      */
  547. X     StoreCursors();
  548. X     
  549. X     /* 
  550. X      * grab the mouse buttons according to the map structure
  551. X      */
  552. X     Grab_Buttons();
  553. X     
  554. X     /* 
  555. X      * watch for initial window mapping and window destruction
  556. X      */
  557. X     
  558. X     errorStatus = False;
  559. X     swa.event_mask = (SubstructureRedirectMask | FocusChangeMask |
  560. X               (NeedRootInput ? EVENTMASK |
  561. X            OwnerGrabButtonMask : 0));
  562. X     XChangeWindowAttributes(dpy, RootWindow(dpy, scr), CWEventMask, &swa);
  563. X     XSync(dpy, False);
  564. X     if (errorStatus)
  565. X      Error("Hmmm.. Looks like you're running another window manager!\n");
  566. X     /*
  567. X      * Before we go creating more windows, we buzz through the ones that
  568. X      * are currently mapped and reparent and/or select on them as necessary
  569. X      * (for autoraise and titles).
  570. X      */
  571. X     
  572. X     if (XQueryTree(dpy, DefaultRootWindow(dpy), &junk, &junk, &kiddies,
  573. X            &nkids)) {
  574. X      int i;
  575. X
  576. X      for (i = 0; i < (int)nkids; i++) {
  577. X           XWindowAttributes xwa;
  578. X           Window transient;
  579. X           AwmInfoPtr awi;
  580. X           unsigned long event_mask;
  581. X           
  582. X           XGetWindowAttributes(dpy, kiddies[i], &xwa);
  583. X           
  584. X           /* check to see if it's a popup or something */
  585. X           XGetTransientForHint(dpy, kiddies[i], &transient);
  586. X           if (xwa.class == InputOutput && xwa.map_state == IsViewable &&
  587. X           xwa.override_redirect == False && transient == None) {
  588. X            awi = RegisterWindow(kiddies[i]);
  589. X            awi->state |= ST_PLACED;
  590. X            /* Possibly add a frame */
  591. X            FDecorate(kiddies[i],0,0,0,0);
  592. X            event_mask = PropertyChangeMask | FocusChangeMask;
  593. X            if (!awi->frame || !FrameFocus)
  594. X             event_mask |= (EnterWindowMask | LeaveWindowMask);
  595. X#ifndef RAINBOW
  596. X            SetBorderPixmaps(awi, GrayPixmap);
  597. X#else
  598. X            SetBorderPixmaps(awi, awi->grayPixmap);
  599. X#endif
  600. X            XSelectInput(dpy, kiddies[i], event_mask);
  601. X           }
  602. X      }
  603. X      if (kiddies && *kiddies)
  604. X          XFree(kiddies);
  605. X     }
  606. X     /*
  607. X      * Calculate size of the resize pop-up window.
  608. X      */
  609. X     valuemask = CWBorderPixel | CWBackPixel;
  610. X     swa.border_pixel = PBorder;
  611. X     swa.background_pixel = PBackground;
  612. X     if (SaveUnder) {
  613. X      swa.save_under = True;
  614. X      valuemask |= CWSaveUnder;
  615. X     }
  616. X     str_width = XTextWidth(PFontInfo, PText, strlen(PText));
  617. X     pop_width = str_width + (PPadding << 1);
  618. X     PWidth = pop_width + (PBorderWidth << 1);
  619. X     pop_height = PFontInfo->ascent + PFontInfo->descent + (PPadding << 1);
  620. X     PHeight = pop_height + (PBorderWidth << 1);
  621. X
  622. X     /*
  623. X      * Create the pop-up window.  Create it at (0, 0) for now.  We will
  624. X      * move it where we want later.
  625. X      */
  626. X     Pop = XCreateWindow(dpy, RootWindow(dpy, scr),
  627. X             0, 0,
  628. X             pop_width, pop_height,
  629. X             PBorderWidth,
  630. X             0,
  631. X             CopyFromParent,
  632. X             CopyFromParent,
  633. X             valuemask,
  634. X             &swa);
  635. X     if (Pop == FAILURE)
  636. X      Error("Can't create pop-up dimension display window.");
  637. X     
  638. X     /*
  639. X      * Create graphics context.
  640. X      */
  641. X     xgc.font = IFontInfo->fid;
  642. X     xgc.graphics_exposures = FALSE;
  643. X     xgc.foreground = IForeground;
  644. X     xgc.background = IBackground;
  645. X     IconGC = XCreateGC(dpy, 
  646. X            RootWindow(dpy, scr),
  647. X            (GCForeground | GCBackground | GCGraphicsExposures |
  648. X             GCFont), &xgc);
  649. X     
  650. X     xgc.foreground = PForeground;
  651. X     xgc.background = PBackground;
  652. X     xgc.font = PFontInfo->fid;
  653. X     PopGC = XCreateGC(dpy, 
  654. X               RootWindow(dpy, scr),
  655. X               (GCForeground | GCBackground | GCFont), &xgc);
  656. X     xgc.line_width = DRAW_WIDTH;
  657. X     xgc.foreground = DRAW_VALUE;
  658. X     xgc.function = DRAW_FUNC;
  659. X     xgc.subwindow_mode = IncludeInferiors;
  660. X     DrawGC = XCreateGC(dpy, RootWindow(dpy, scr), 
  661. X            GCLineWidth | GCForeground | GCFunction |
  662. X            GCSubwindowMode, &xgc);
  663. X
  664. X     /*
  665. X      * As our last "startup" task, invoke the execfile if was specified.
  666. X      */
  667. X     if (!desktop_execd) {
  668. X      if (access(execfile, X_OK) == 0) {
  669. X           if (fork() == 0) {
  670. X            setpgrp(0, getpid());
  671. X            signal(SIGHUP, SIG_DFL);
  672. X            signal(SIGQUIT, SIG_DFL);
  673. X            signal(SIGINT, SIG_DFL);
  674. X            execl("/bin/sh", "sh", "-c", execfile, 0);
  675. X            _exit(127);
  676. X           }
  677. X           else
  678. X            desktop_execd = TRUE;
  679. X      }
  680. X     }
  681. X     /*
  682. X      * Tell the user we're alive and well.
  683. X      */
  684. X     XBell(dpy, VOLUME_PERCENTAGE(Volume));
  685. X     
  686. X     /* 
  687. X      * Main command loop.
  688. X      */
  689. X     while (TRUE) {
  690. X      
  691. X      delta_done = func_stat = FALSE;
  692. X      
  693. X      /*
  694. X       * Get the next mouse button event.  Spin our wheels until
  695. X       * a ButtonPressed event is returned.
  696. X       * Note that mouse events within an icon window are handled
  697. X       * in the "GetButton" function or by the icon's owner if
  698. X       * it is not awm.
  699. X       */
  700. X      while (TRUE) {
  701. X           if (!GetButton(&button_event))
  702. X            continue;
  703. X           else if (button_event.type == ButtonPress)
  704. X            break;
  705. X      }
  706. X      bwin = button_event.xbutton.window;
  707. X      /* save mouse coords in case we want them later for a delta action */
  708. X      down_x = button_event.xbutton.x;
  709. X      down_y = button_event.xbutton.y;
  710. X      
  711. X      /*
  712. X       * Okay, determine the event window and mouse coordinates.
  713. X       */
  714. X      status = XTranslateCoordinates(dpy, 
  715. X                     bwin,
  716. X                     RootWindow(dpy, scr),
  717. X                     button_event.xbutton.x, 
  718. X                     button_event.xbutton.y,
  719. X                     &x, &y,
  720. X                     &event_win);
  721. X      if (status == 0)
  722. X           continue;
  723. X      
  724. X      awi = GetAwmInfo(bwin);
  725. X      if (!awi)
  726. X           continue;
  727. X
  728. X          if (awi->frame == bwin)
  729. X               context = BORDER;
  730. X      else if (awi->title == bwin)
  731. X           context = TITLE;
  732. X      else if (IsGadgetWin(bwin, &num))
  733. X           context = GADGET | (1 << (num + BITS_USED));
  734. X      else if (awi->icon == bwin)
  735. X           context = ICON;
  736. X      else if (awi->client == RootWindow(dpy, scr)) {
  737. X           event_win = RootWindow(dpy, scr);
  738. X           context = ROOT;
  739. X      }
  740. X      else
  741. X           context = WINDOW;
  742. X
  743. X      /*
  744. X       * Get the button event detail.
  745. X       */
  746. X      lo = button_event.xbutton.button;
  747. X      hi = button_event.xbutton.state;
  748. X      
  749. X      /*
  750. X       * Determine which function was selected and invoke it.
  751. X       */
  752. X      for(bptr = Blist; bptr; bptr = bptr->next) {
  753. X           if ((bptr->button != lo) ||
  754. X           (((int)bptr->mask & ModMask) != hi))
  755. X            continue;
  756. X           
  757. X           if ((bptr->context & context) != context) {
  758. X            continue;
  759. X               }
  760. X           if (!(bptr->mask & ButtonDown))
  761. X            continue;
  762. X           
  763. X           /*
  764. X        * Found a match! Invoke the function.
  765. X        */
  766. X           if ((*bptr->func)(event_win, (int)bptr->mask & ModMask,
  767. X                 bptr->button,
  768. X                 x, y,
  769. X                 bptr->menu, bptr->menuname))
  770. X            func_stat = TRUE;
  771. X           break;
  772. X      }
  773. X      
  774. X      /*
  775. X       * If the function ate the ButtonUp event, then restart the loop.
  776. X       */
  777. X      
  778. X      if (func_stat)
  779. X           continue;
  780. X      while (TRUE) {
  781. X           /*
  782. X        * Wait for the next button event.
  783. X        */
  784. X           if (XPending(dpy) && GetButton(&button_event)) {
  785. X            bwin = button_event.xbutton.window;
  786. X            /*
  787. X             * If it's not a release of button that was pressed,
  788. X             * don't do the function bound to 'ButtonUp'.
  789. X             */
  790. X            if (button_event.type != ButtonRelease)
  791. X             break;
  792. X            if (lo != button_event.xbutton.button)
  793. X             break;
  794. X            if ((hi | ButtonMask(lo)) != button_event.xbutton.state)
  795. X             break;
  796. X            /*
  797. X             * Okay, determine the event window and mouse coordinates.
  798. X             */
  799. X            status = XTranslateCoordinates(dpy, 
  800. X                           bwin,
  801. X                           RootWindow(dpy, scr),
  802. X                           button_event.xbutton.x,
  803. X                           button_event.xbutton.y,
  804. X                           &x, &y,
  805. X                           &event_win);
  806. X            if (status == BadWindow)
  807. X             break;
  808. X            awi = GetAwmInfo(bwin);
  809. X            if (!awi)
  810. X             continue;
  811. X            if (awi->frame == bwin)
  812. X             context = BORDER;
  813. X            else if (awi->title == bwin)
  814. X             context = TITLE;
  815. X            else if (IsGadgetWin(bwin, &num))
  816. X             context = GADGET | (1 << (num + BITS_USED));
  817. X            else if (awi->icon == bwin)
  818. X             context = ICON;
  819. X            else if (awi->client == RootWindow(dpy, scr)) {
  820. X             event_win = RootWindow(dpy, scr);
  821. X             context = ROOT;
  822. X            }
  823. X            else
  824. X             context = WINDOW;
  825. X            /*
  826. X             * Determine which function was selected and invoke it.
  827. X             */
  828. X            for(bptr = Blist; bptr; bptr = bptr->next) {
  829. X             
  830. X             if ((bptr->button != lo) ||
  831. X                 (((int)bptr->mask & ModMask) != hi))
  832. X                  continue;
  833. X             
  834. X             if (!((bptr->context & context) == context)) {
  835. X                  continue;
  836. X                         }
  837. X             
  838. X             if (!(bptr->mask & ButtonUp))
  839. X                  continue;
  840. X             
  841. X             /*
  842. X              * Found a match! Invoke the function.
  843. X              */
  844. X             
  845. X             (*bptr->func)(event_win,
  846. X                       (int)bptr->mask & ModMask,
  847. X                       bptr->button,
  848. X                       x, y,
  849. X                       bptr->menu, bptr->menuname);
  850. X             break;
  851. X            }
  852. X            break;
  853. X           }
  854. X           XQueryPointer(dpy, RootWindow(dpy, scr),
  855. X                 &root, &junk, &root_x, &root_y, &cur_x, &cur_y,
  856. X                 &ptrmask);
  857. X           if (!delta_done &&
  858. X           (abs(cur_x - x) > Delta || abs(cur_y - y) > Delta)) {
  859. X            /*
  860. X             * Delta functions are done once (and only once.)
  861. X             */
  862. X            delta_done = TRUE;
  863. X            
  864. X            /*
  865. X             * Determine the new event window's coordinates from the
  866. X             * original ButtonPress event.
  867. X             */
  868. X            status = XTranslateCoordinates(dpy, bwin,
  869. X                           RootWindow(dpy, scr),
  870. X                           down_x, down_y, &x, &y,
  871. X                           &junk);
  872. X            if (status == 0)
  873. X             break;
  874. X
  875. X            /*
  876. X             * Determine the event window and context.
  877. X             */
  878. X            if (awi->frame == bwin)
  879. X             context = BORDER;
  880. X            else if (awi->title == bwin)
  881. X             context = TITLE;
  882. X            else if (IsGadgetWin(bwin, &num))
  883. X             context = GADGET | (1 << (num + BITS_USED));
  884. X            else if (awi->icon == bwin)
  885. X             context = ICON;
  886. X            else if (awi->client == RootWindow(dpy, scr)) {
  887. X             event_win = RootWindow(dpy, scr);
  888. X             context = ROOT;
  889. X            }
  890. X            else
  891. X             context = WINDOW;
  892. X            /*
  893. X             * Determine which function was selected and invoke it.
  894. X             */
  895. X            for(bptr = Blist; bptr; bptr = bptr->next) {
  896. X             
  897. X             if ((bptr->button != lo) ||
  898. X                 (((int)bptr->mask & ModMask) != hi))
  899. X                  continue;
  900. X             
  901. X             if (!((bptr->context & context) == context))
  902. X                  continue;
  903. X             
  904. X             if (!(bptr->mask & DeltaMotion))
  905. X                  continue;
  906. X             
  907. X             /*
  908. X              * Found a match! Invoke the function.
  909. X              */
  910. X             
  911. X             if ((*bptr->func)(event_win,
  912. X                       (int)bptr->mask & ModMask,
  913. X                       bptr->button,
  914. X                       x, y,
  915. X                       bptr->menu, bptr->menuname)) {
  916. X                  func_stat = TRUE;
  917. X                  break;
  918. X             }
  919. X            }
  920. X            /*
  921. X             * If the function ate the ButtonUp event,
  922. X             * then restart the loop.
  923. X             */
  924. X            
  925. X            if (func_stat)
  926. X             break;
  927. X           }
  928. X      }
  929. X     }
  930. X}
  931. X
  932. X/*
  933. X * Get defaults from the resource manager. Most of these things used to be
  934. X * in the rc file, but they really belong here, I think.
  935. X */
  936. XGet_Defaults()
  937. X{
  938. X     /*
  939. X      * Get the pixmap search path, if it exists.
  940. X      */
  941. X     awmPath = GetStringRes("path", (char *) NULL);
  942. X
  943. X     /* Default foreground/background colors (text) */
  944. X     Foreground = GetStringRes("foreground", "black");
  945. X     Background = GetStringRes("background", "white");
  946. X     Reverse = GetBoolRes("reverse", FALSE);
  947. X     
  948. X     if (Reverse) { /* Swap the foreground and background */
  949. X      char *tmp;
  950. X      
  951. X      tmp = Foreground;
  952. X      Foreground = Background;
  953. X          Background = tmp;
  954. X     }
  955. X     WBorder = GetStringRes("border.foreground", Foreground);
  956. X     
  957. X     Autoselect = GetBoolRes("autoselect", FALSE);
  958. X     Autoraise = GetBoolRes("autoraise", FALSE);
  959. X     Borders = GetBoolRes("borderContexts", FALSE);
  960. X     ConstrainResize = GetBoolRes("constrainResize", FALSE);
  961. X     FrameFocus = GetBoolRes("frameFocus", FALSE);
  962. X     Freeze = GetBoolRes("freeze", FALSE);
  963. X     Grid = GetBoolRes("grid", FALSE);
  964. X     InstallColormap = GetBoolRes("installColormap", FALSE);
  965. X     Titles = GetBoolRes("titles", FALSE);
  966. X     IconLabels = GetBoolRes("icon.labels", FALSE);
  967. X     ILabelTop = GetBoolRes("icon.labelTop", FALSE);
  968. X     PushDown = GetBoolRes("title.push", FALSE);
  969. X     UseGadgets = GetBoolRes("gadgets", FALSE);
  970. X     Hilite = GetBoolRes("hilite", FALSE);
  971. X     BorderHilite = GetBoolRes("border.hilite", Hilite);
  972. X     RootResizeBox = GetBoolRes("rootResizeBox", FALSE);
  973. X     ResizeRelative = GetBoolRes("resizeRelative", FALSE);
  974. X     NIcon = GetBoolRes("normali", TRUE);
  975. X     ShowName = GetBoolRes("showName", TRUE);
  976. X     NWindow = GetBoolRes("normalw", TRUE);
  977. X     Push = GetBoolRes("pushRelative", FALSE);
  978. X     SaveUnder = GetBoolRes("saveUnder", FALSE);
  979. X     Wall = GetBoolRes("wall", FALSE);
  980. X     WarpOnRaise = GetBoolRes("warpOnRaise", FALSE);
  981. X     WarpOnIconify = GetBoolRes("warpOnIconify", FALSE);
  982. X     WarpOnDeIconify = GetBoolRes("warpOnDeIconify", FALSE);
  983. X     Zap = GetBoolRes("zap", FALSE);
  984. X     
  985. X     HIconPad = GetIntRes("icon.hPad", DEF_ICON_PAD);
  986. X     VIconPad = GetIntRes("icon.vPad", DEF_ICON_PAD);
  987. X     RaiseDelay = GetIntRes("raiseDelay", DEF_RAISE_DELAY);
  988. X     PBorderWidth = GetIntRes("popup.borderWidth", DEF_POP_BORDER_WIDTH);
  989. X     IBorderWidth = GetIntRes("icon.borderWidth", DEF_ICON_BORDER_WIDTH);
  990. X     PPadding = GetIntRes("popup.pad", DEF_POP_PAD);
  991. X     MBorderWidth = GetIntRes("menu.borderWidth", DEF_MENU_BORDER_WIDTH);
  992. X     MItemBorder = GetIntRes("menu.itemBorder", 1);
  993. X     MDelta = GetIntRes("menu.delta", DEF_MENU_DELTA);
  994. X     MPad = GetIntRes("menu.pad", DEF_MENU_PAD);
  995. X     Delta = GetIntRes("delta", DEF_DELTA);
  996. X     Volume = GetIntRes("volume", DEF_VOLUME);
  997. X     Pushval = GetIntRes("push", DEF_PUSH);
  998. X     BContext = GetIntRes("borderContext.width", DEF_BCONTEXT_WIDTH);
  999. X
  1000. X     ForeColor = GetColorRes("foreground", BlackPixel(dpy, scr));
  1001. X     BackColor = GetColorRes("background", WhitePixel(dpy, scr));
  1002. X     IForeground = GetColorRes("icon.foreground", ForeColor);
  1003. X     IBackground = GetColorRes("icon.background", BackColor);
  1004. X     IBorder = GetColorRes("icon.border", IForeground);
  1005. X     ITextForeground = GetColorRes("icon.text.foreground", IForeground);
  1006. X     ITextBackground = GetColorRes("icon.text.background", IBackground);
  1007. X     PBorder = GetColorRes("popup.border", ForeColor);
  1008. X     PForeground = GetColorRes("popup.foreground", PBorder);
  1009. X     PBackground = GetColorRes("popup.background", BackColor);
  1010. X     MForeground = GetColorRes("menu.foreground", ForeColor);
  1011. X     MBackground = GetColorRes("menu.background", BackColor);
  1012. X     MBorder = GetColorRes("menu.border", MForeground);
  1013. X
  1014. X     /*
  1015. X      * Create and store the grey and solid pixmaps, and default icon pixmap
  1016. X      */
  1017. X     GrayPixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  1018. X                          gray_bits,
  1019. X                          gray_width, gray_height,
  1020. X                          ForeColor,
  1021. X                          BackColor,
  1022. X                          (unsigned)DefaultDepth(dpy,scr));
  1023. X
  1024. X     SolidPixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  1025. X                           solid_bits,
  1026. X                           solid_width, solid_height,
  1027. X                           ForeColor,
  1028. X                           BackColor,
  1029. X                           (unsigned)DefaultDepth(dpy,
  1030. X                                      scr));
  1031. X     
  1032. X     IDefPixmap = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  1033. X                           xlogo32_bits,
  1034. X                           xlogo32_width, xlogo32_height,
  1035. X                           IForeground,
  1036. X                           IBackground,
  1037. X                           (unsigned)DefaultDepth(dpy,
  1038. X                                      scr));
  1039. X     IFontInfo = GetFontRes("icon.font", DEF_ICON_FONT);
  1040. X     PFontInfo = GetFontRes("popup.font", DEF_POPUP_FONT);
  1041. X     MFontInfo = GetFontRes("menu.font", DEF_MENU_FONT);
  1042. X     MBoldFontInfo = GetFontRes("menu.boldFont", DEF_BOLD_FONT);
  1043. X
  1044. X     
  1045. X     IBackPixmap = GetPixmapRes("icon.backpixmap", GrayPixmap, IForeground,
  1046. X                IBackground);
  1047. X     IDefPixmap =  GetPixmapRes("icon.defpixmap", IDefPixmap, IForeground,
  1048. X                IBackground);
  1049. X
  1050. X#ifdef NEATEN
  1051. X     AbsMinWidth = GetIntRes("neaten.absMinWidth", DEFAULT_ABS_MIN);
  1052. X     AbsMinHeight = GetIntRes("neaten.absMinHeight", DEFAULT_ABS_MIN);
  1053. X     
  1054. X     RetainSize = GetBoolRes("neaten.retainSize", TRUE);
  1055. X     KeepOpen = GetBoolRes("neaten.keepOpen", TRUE);
  1056. X     Fill = GetBoolRes("neaten.fill", TRUE);
  1057. X     UsePriorities = GetBoolRes("neaten.usePriorities", TRUE);
  1058. X     FixTopOfStack = GetBoolRes("neaten.fixTopOfStack", TRUE);
  1059. X     
  1060. X     PrimaryIconPlacement = GetStringRes("neaten.primaryIconPlacement",
  1061. X                     DEF_PRIMARY_PLACEMENT);
  1062. X     SecondaryIconPlacement = GetStringRes("neaten.secondaryIconPlacement",
  1063. X                       DEF_SECONDARY_PLACEMENT);
  1064. X#endif
  1065. X     
  1066. X     Leave_void
  1067. X}
  1068. X
  1069. X/*
  1070. X * Look up string resource "string". If undefined, return "def_val"
  1071. X */
  1072. Xchar *GetStringRes(string, def_val)
  1073. Xchar *string, *def_val;
  1074. X{
  1075. X     char *cp;
  1076. X     
  1077. X     Entry("GetStringRes")
  1078. X     
  1079. X     if ((cp = XGetDefault(dpy, NAME, string)) ||
  1080. X     (cp = XGetDefault(dpy, CLASS, string))) {
  1081. X      if (!strlen(cp))
  1082. X           Leave(def_val)
  1083. X      else
  1084. X           Leave(cp)
  1085. X     }
  1086. X     Leave(def_val)
  1087. X}
  1088. X
  1089. X/*
  1090. X * Look up boolean resource "string". If undefined, return "def_val"
  1091. X */
  1092. XBoolean GetBoolRes(string, def_val)
  1093. Xchar *string;
  1094. XBoolean def_val;
  1095. X{
  1096. X     char *cp;
  1097. X     
  1098. X     Entry("GetBoolRes")
  1099. X     
  1100. X     if ((cp = XGetDefault(dpy, NAME, string)) ||
  1101. X     (cp = XGetDefault(dpy, CLASS, string)))
  1102. X      if (Pred(cp) > 0)
  1103. X        def_val = TRUE;
  1104. X     Leave(def_val)
  1105. X}
  1106. X
  1107. X/*
  1108. X * Look up integer resource "string". If undefined or non-numeric,
  1109. X * return def_val.
  1110. X */
  1111. Xint GetIntRes(string, def_val)
  1112. Xchar *string;
  1113. Xint def_val;
  1114. X{
  1115. X     char *cp;
  1116. X     
  1117. X     Entry("GetIntRes")
  1118. X     
  1119. X     if ((cp = XGetDefault(dpy, NAME, string)) ||
  1120. X     (cp = XGetDefault(dpy, CLASS, string))) {
  1121. X      if (!strlen(cp) || !((*cp >= '0' && *cp <= '9') || *cp == '-'))
  1122. X           Leave(def_val)
  1123. X      Leave(atoi(cp))
  1124. X     }
  1125. X     Leave(def_val)
  1126. X}
  1127. X
  1128. X/*
  1129. X * Try to load pixmap file named by resource "string". Return 0 if
  1130. X * unsuccessful. Otherwise, set width, height and return data.
  1131. X */
  1132. Xchar *GetPixmapDataRes(string, wide, high)
  1133. Xchar *string;
  1134. Xunsigned int *wide, *high;
  1135. X{
  1136. X     char *cp, *cp2;
  1137. X
  1138. X     Entry("GetPixmapDataRes")
  1139. X     
  1140. X     if ((cp = XGetDefault(dpy, NAME, string)) ||
  1141. X     (cp = XGetDefault(dpy, CLASS, string))) {
  1142. X      char *data;
  1143. X      int junk;
  1144. X      
  1145. X      cp2 = expand_from_path(cp);
  1146. X      if (!cp2) {
  1147. X           fprintf(stderr, "awm: Can't find pixmap file '%s' for '%s'\n",
  1148. X               cp, string);
  1149. X           Leave(0)
  1150. X      }
  1151. X      if (XmuReadBitmapDataFromFile(cp2, wide, high, &data, &junk, &junk)
  1152. X          != BitmapSuccess) {
  1153. X           fprintf(stderr, "awm: Can't read pixmap file '%s' for '%s'.\n",
  1154. X               cp, string);
  1155. X      }
  1156. X      else {
  1157. X           Leave(data)
  1158. X      }
  1159. X     }
  1160. X     Leave(0)
  1161. X}
  1162. X
  1163. X/*
  1164. X * Try to allocate pixmap resources named by "string", return "def_pix"
  1165. X * if not found.
  1166. X */
  1167. XPixmap GetPixmapRes(string, def_pix, fg, bg)
  1168. Xchar *string;
  1169. XPixmap def_pix;
  1170. XPixel fg, bg;
  1171. X{
  1172. X     char *data;
  1173. X     Pixmap tmp;
  1174. X     unsigned int wide, high;
  1175. X
  1176. X     Entry("GetPixmapRes")
  1177. X
  1178. X     if (data = GetPixmapDataRes(string, &wide, &high)) {
  1179. X      tmp = XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  1180. X                        data, wide, high, fg, bg,
  1181. X                        (unsigned) DefaultDepth(dpy, scr));
  1182. X      XFree(data);
  1183. X      if (!tmp) {
  1184. X           fprintf(stderr,
  1185. X               "awm: Can't create pixmap '%s', using default.\n",
  1186. X               string);
  1187. X           tmp = def_pix;
  1188. X      }
  1189. X     }
  1190. X     else
  1191. X      tmp = def_pix;
  1192. X     Leave(tmp)
  1193. X     }
  1194. X
  1195. X/*
  1196. X * Try to allocate color resource named by "string", return "color"
  1197. X * if not found.This routine is only used for allocating colors from
  1198. X * the default colormap.
  1199. X */
  1200. XPixel GetColorRes(string, color)
  1201. Xchar *string;
  1202. XPixel color;
  1203. X{
  1204. X     char *cp;
  1205. X     Pixel tmp_color;
  1206. X     Boolean status;
  1207. X     extern Pixel LookupColor();
  1208. X     
  1209. X     Entry("GetColorRes")
  1210. X     
  1211. X     if ((cp = XGetDefault(dpy, NAME, string)) ||
  1212. X     (cp = XGetDefault(dpy, CLASS, string))) {
  1213. X      tmp_color = LookupColor(cp, DefaultColormap(dpy, scr), &status);
  1214. X      if (!status) /* lookup succeeded */
  1215. X           Leave(tmp_color)
  1216. X      else
  1217. X           tmp_color = color;
  1218. X     }
  1219. X     else
  1220. X      tmp_color = color;
  1221. X     Leave(tmp_color)
  1222. X}
  1223. X
  1224. X/*
  1225. X * Try and get font resource "string", using "default" if not found. If
  1226. X * neither are available, use server default.
  1227. X */
  1228. X
  1229. XXFontStruct *GetFontRes(string, dflt)
  1230. Xchar *string, *dflt;
  1231. X{
  1232. X     char *cp;
  1233. X     XFontStruct *tmp;
  1234. X     static XFontStruct *def_font = 0;
  1235. X     
  1236. X     Entry("GetFontRes")
  1237. X     
  1238. X     if (!def_font)
  1239. X      def_font = XLoadQueryFont(dpy, DEF_FONT);
  1240. X     
  1241. X     if ((cp = XGetDefault(dpy, NAME, string)) ||
  1242. X     (cp = XGetDefault(dpy, CLASS, string))) {
  1243. X      if (tmp = XLoadQueryFont(dpy, cp))
  1244. X           Leave(tmp)
  1245. X      else if (dflt)
  1246. X           fprintf(stderr, "awm: Can't load %s '%s', trying '%s'.\n",
  1247. X               string, cp, dflt);
  1248. X     }
  1249. X     if (!dflt) /* NULL means we're not supposed to try again */
  1250. X      Leave(NULL)
  1251. X     if (tmp = XLoadQueryFont(dpy, dflt))
  1252. X      Leave(tmp)
  1253. X     else
  1254. X      fprintf(stderr, "awm: Can't open default font '%s', using server default.\n", dflt);
  1255. X     Leave(def_font)
  1256. X}
  1257. X
  1258. XAwmInfoPtr GetAwmInfo(w)
  1259. XWindow w;
  1260. X{
  1261. X     static AwmInfoPtr tmp;
  1262. X     
  1263. X     Entry("GetAwmInfo")
  1264. X     
  1265. X     if (!XFindContext(dpy, w, AwmContext, (caddr_t *) &tmp))
  1266. X      Leave(tmp)
  1267. X     else
  1268. X      Leave((AwmInfoPtr)NULL)
  1269. X}
  1270. X
  1271. XAwmInfoPtr RegisterWindow(w)
  1272. XWindow w;
  1273. X{
  1274. X     AwmInfoPtr tmp;
  1275. X     XClassHint clh;
  1276. X     XWMHints *wm_hints;
  1277. X     char *cp;
  1278. X
  1279. X     Entry("RegisterWindow")
  1280. X     
  1281. X     tmp = (AwmInfoPtr)malloc(sizeof(AwmInfo));
  1282. X     if (tmp == (AwmInfoPtr)NULL) {
  1283. X      fprintf(stderr, "awm: Woe! No memory to register window.\n");
  1284. X      Leave((AwmInfoPtr)NULL)
  1285. X     }
  1286. X     tmp->client = w;
  1287. X     tmp->title = tmp->frame = tmp->icon = (Window)0;
  1288. X     tmp->gadgets = (Window *)0;
  1289. X     tmp->name = (char *)0;
  1290. X     tmp->own = (Boolean)FALSE;
  1291. X     tmp->back = tmp->bold = tmp->BC_back = tmp->BC_bold =
  1292. X      tmp->iconPixmap = (Pixmap)0;
  1293. X     tmp->state = ST_WINDOW;
  1294. X#ifdef WMSTATE
  1295. X     tmp->wm_state.icon=0;
  1296. X     tmp->wm_state.state=NormalState;
  1297. X     XChangeProperty(dpy,w,wm_state_atom,wm_state_atom,32,PropModeReplace,
  1298. X             (char *) &tmp->wm_state,2);
  1299. X#endif /* WMSTATE */
  1300. X     tmp->winGC = XCreateGC(dpy, w, (unsigned long)0, (XGCValues *) NULL);
  1301. X     /*
  1302. X      * Determine attribute set by first turning on all attributes
  1303. X      * that are set by booleans and then (possibly) override them
  1304. X      * by checking to see what an individual window might want.
  1305. X      */
  1306. X     tmp->attrs = AT_NONE;
  1307. X     if (Titles)
  1308. X      tmp->attrs |= AT_TITLE;
  1309. X     if (UseGadgets)
  1310. X      tmp->attrs |= AT_GADGETS;
  1311. X     if (Borders)
  1312. X      tmp->attrs |= AT_BORDER;
  1313. X     if (Autoraise)
  1314. X      tmp->attrs |= AT_RAISE;
  1315. X     if (IconLabels)
  1316. X      tmp->attrs |= AT_ICONLABEL;
  1317. X     if (wm_hints = XGetWMHints(dpy, w)) {
  1318. X      if (wm_hints->input)
  1319. X             tmp->attrs |= AT_INPUT;
  1320. X      XFree(wm_hints);
  1321. X     }
  1322. X#ifdef RAINBOW
  1323. X     tmp->foreColor = ForeColor;
  1324. X     tmp->backColor = BackColor;
  1325. X     tmp->grayPixmap = GrayPixmap;
  1326. X     tmp->solidPixmap = SolidPixmap;
  1327. X#endif
  1328. X     clh.res_name = clh.res_class = (char *)NULL;
  1329. X     XGetClassHint(dpy, w, &clh);
  1330. X     if (clh.res_class) {
  1331. X#ifdef RAINBOW
  1332. X      Pixel tmp_color;
  1333. X      Boolean status;
  1334. X      
  1335. X      if (cp = (XGetDefault(dpy, clh.res_class, "wm_option.foreground"))){
  1336. X          tmp_color = LookupColor( cp, DefaultColormap( dpy, scr ), & status );
  1337. X          if( !status )
  1338. X              tmp->foreColor = tmp_color;
  1339. X      }
  1340. X
  1341. X      if (cp = (XGetDefault(dpy, clh.res_class, "wm_option.background"))){
  1342. X          tmp_color = LookupColor( cp, DefaultColormap( dpy, scr ), & status );
  1343. X          if( !status )
  1344. X              tmp->backColor = tmp_color;
  1345. X      }
  1346. X#endif
  1347. X      
  1348. X      if (cp = (XGetDefault(dpy, clh.res_class, "wm_option.title")))
  1349. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_TITLE, Pred(cp));
  1350. X      
  1351. X      if (cp = (XGetDefault(dpy, clh.res_class, "wm_option.gadgets")))
  1352. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_GADGETS, Pred(cp));
  1353. X
  1354. X      if (cp = (XGetDefault(dpy, clh.res_class,"wm_option.borderContext")))
  1355. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_BORDER, Pred(cp));
  1356. X
  1357. X      if (cp = (XGetDefault(dpy, clh.res_class, "wm_option.autoRaise")))
  1358. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_RAISE, Pred(cp));
  1359. X
  1360. X      if (cp = (XGetDefault(dpy, clh.res_class, "wm_option.icon.labels")))
  1361. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_ICONLABEL, Pred(cp));
  1362. X     }
  1363. X     if (clh.res_name) {
  1364. X#ifdef RAINBOW
  1365. X      Pixel tmp_color;
  1366. X      Boolean status;
  1367. X
  1368. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.foreground"))){
  1369. X          tmp_color = LookupColor( cp, DefaultColormap( dpy, scr ), & status );
  1370. X          if( !status )
  1371. X              tmp->foreColor = tmp_color;
  1372. X      }
  1373. X
  1374. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.background"))){
  1375. X          tmp_color = LookupColor( cp, DefaultColormap( dpy, scr ), & status );
  1376. X          if( !status )
  1377. X              tmp->backColor = tmp_color;
  1378. X      }
  1379. X#endif
  1380. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.title")))
  1381. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_TITLE, Pred(cp));
  1382. X      
  1383. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.gadgets")))
  1384. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_GADGETS, Pred(cp));
  1385. X
  1386. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.borderContext")))
  1387. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_BORDER, Pred(cp));
  1388. X
  1389. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.autoRaise")))
  1390. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_RAISE, Pred(cp));
  1391. X
  1392. X      if (cp = (XGetDefault(dpy, clh.res_name, "wm_option.icon.labels")))
  1393. X           tmp->attrs = SetOptFlag(tmp->attrs, AT_ICONLABEL, Pred(cp));
  1394. X     }
  1395. X#ifdef RAINBOW
  1396. X     /* Has a different fore/back colour been given? */
  1397. X     if( (tmp->foreColor != ForeColor) || (tmp->backColor != BackColor) ){
  1398. X      /*
  1399. X       * Create and store the grey and solid pixmaps
  1400. X       */
  1401. X         tmp->grayPixmap = 
  1402. X           XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  1403. X                       gray_bits,
  1404. X                       gray_width, gray_height,
  1405. X                       tmp->foreColor,
  1406. X                       tmp->backColor,
  1407. X                       (unsigned)DefaultDepth(dpy, scr));
  1408. X         
  1409. X         tmp->solidPixmap = 
  1410. X           XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  1411. X                       solid_bits,
  1412. X                       solid_width, solid_height,
  1413. X                       tmp->foreColor,
  1414. X                       tmp->backColor,
  1415. X                       (unsigned)DefaultDepth(dpy, scr));
  1416. X         
  1417. X     }
  1418. X#endif
  1419. X     XSaveContext(dpy, w, AwmContext, (caddr_t) tmp);
  1420. X     Leave(tmp)
  1421. X}
  1422. X
  1423. X/*
  1424. X * Sets bit "flag" conditionally, based on state of "mask" and
  1425. X * "predicate" (mask denotes current state, predicate denotes
  1426. X * whether change is desired).
  1427. X */
  1428. Xint SetOptFlag(mask, flag, predicate)
  1429. Xint mask, flag, predicate;
  1430. X{
  1431. X     Entry("SetOptFlag")
  1432. X
  1433. X     switch (predicate) {
  1434. X     case -1:
  1435. X      Leave(mask)
  1436. X          break;
  1437. X
  1438. X     case 0:
  1439. X          if (mask & flag)
  1440. X           Leave(mask ^ flag)
  1441. X          else
  1442. X           Leave(mask)
  1443. X      break;
  1444. X
  1445. X     case 1:
  1446. X      Leave(mask | flag)
  1447. X      break;
  1448. X     }
  1449. X     Leave(-1);
  1450. X}
  1451. X
  1452. X/*
  1453. X * check whether a string denotes an "on" or "off" value. Return 0
  1454. X * if "off", 1 if "on" and -1 if undefined (or null).
  1455. X */
  1456. XPred(s)
  1457. Xchar *s;
  1458. X{
  1459. X     int i, len;
  1460. X     char *tmp;
  1461. X     Boolean ret = -1;
  1462. X     Entry("Pred")
  1463. X
  1464. X     if (!s)
  1465. X      Leave(-1)
  1466. X     len = strlen(s);
  1467. X     if (!len)
  1468. X      Leave(-1)
  1469. X     tmp = (char *)malloc(len + 1);
  1470. X     if (!tmp) {
  1471. X      fprintf(stderr, "awm: Pred: Can't allocate storage for '%s'!\n", s);
  1472. X      Leave(-1)
  1473. X     }
  1474. X     strcpy(tmp, s);
  1475. X     for (i = 0; i < len; i++)
  1476. X      if (tmp[i] >= 'A' && tmp[i] <= 'Z')
  1477. X           tmp[i] += 32;
  1478. X     if (*tmp == 'y' || !strcmp(tmp, "on")
  1479. X     || !strcmp(tmp, "true")
  1480. X     || !strncmp(tmp, "enable", 6))
  1481. X      ret = 1;
  1482. X     else if (*tmp == 'n' || !strcmp(tmp, "off")
  1483. X          || !strcmp(tmp, "false")
  1484. X          || !strncmp(tmp, "disable", 7))
  1485. X      ret = 0;
  1486. X     free(tmp);
  1487. X     Leave(ret)
  1488. X}
  1489. X
  1490. X/*
  1491. X * Initialize the default bindings.  First, write the character array
  1492. X * out to a temp file, then point the parser to it and read it in.
  1493. X * Afterwards, we unlink the temp file.
  1494. X */
  1495. XInitBindings()
  1496. X{
  1497. X     char *mktemp();
  1498. X     char *tempfile;
  1499. X     register FILE *fp;        /* Temporary file pointer. */
  1500. X     register char **ptr;    /* Default bindings string array pointer. */
  1501. X     
  1502. X     Entry("InitBindings")
  1503. X     
  1504. X     /*
  1505. X      * Create and write the temp file.
  1506. X      */
  1507. X     /*
  1508. X      * This used to just call mktemp() on TEMPFILE, which was very
  1509. X      * evil as it involved writing on a string constant. This extra
  1510. X      * mastication is necessary to prevent that.
  1511. X      */
  1512. X     tempfile = (char *)malloc(strlen(TEMPFILE) + 1);
  1513. X     strcpy(tempfile, TEMPFILE);
  1514. X     sfilename = mktemp(tempfile);
  1515. X     if ((fp = fopen(tempfile, "w")) == NULL) {
  1516. X      perror("awm: cannot create temp file");
  1517. X      exit(1);
  1518. X     }
  1519. X     for (ptr = DefaultBindings; *ptr; ptr++) {
  1520. X      fputs(*ptr, fp);
  1521. X      fputc('\n', fp);
  1522. X     }
  1523. X     fclose(fp);
  1524. X     
  1525. X     /*
  1526. X      * Read in the bindings from the temp file and parse them.
  1527. X      */
  1528. X     if ((yyin = fopen(tempfile, "r")) == NULL) {
  1529. X      perror("awm: cannot open temp file");
  1530. X      exit(1);
  1531. X     }
  1532. X     Lineno = 1;
  1533. X     yyparse();
  1534. X     fclose(yyin);
  1535. X     unlink(tempfile);
  1536. X     free(tempfile);
  1537. X     if (Startup_File_Error)
  1538. X      Error("Bad default bindings...aborting");
  1539. X     
  1540. X     /*
  1541. X      * Parse the system startup file, if one exists.
  1542. X      */
  1543. X     if ((yyin = fopen(SYSFILE, "r")) != NULL) {
  1544. X      sfilename = SYSFILE;
  1545. X      Lineno = 1;
  1546. X      yyparse();
  1547. X      fclose(yyin);
  1548. X      if (Startup_File_Error)
  1549. X           Error("Bad system startup file...aborting");
  1550. X     }
  1551. X     Leave_void
  1552. X}
  1553. X
  1554. X/*
  1555. X * Create the menus and alter any appropriate bindings so that the RTL menu
  1556. X * handle is passed along in subsequent actions.
  1557. X */
  1558. XCreate_Menus()
  1559. X{
  1560. X     Binding *bptr;
  1561. X     MenuInfo *minfo;
  1562. X     MenuLink *lnk;
  1563. X     extern MenuInfo *FindMenu();
  1564. X     extern RTLMenu create_menu();
  1565. X     
  1566. X     Entry("Create_Menus")
  1567. X     
  1568. X     /*
  1569. X      * We start with the bindings list because we don't want to bother
  1570. X      * creating a menu that's been declared but not referenced.
  1571. X      */
  1572. X     for(bptr = Blist; bptr; bptr = bptr->next) {
  1573. X      if (bptr->func == DoMenu) {
  1574. X           if (minfo = FindMenu(bptr->menuname))
  1575. X            bptr->menu = create_menu(minfo);
  1576. X           else {
  1577. X            fprintf(stderr, "awm: non-existent menu reference: \"%s\"\n",
  1578. X                bptr->menuname);
  1579. X            Startup_File_Error = TRUE;
  1580. X           }
  1581. X      }
  1582. X     }
  1583. X     for (lnk = Menus; lnk; lnk = lnk->next) {
  1584. X      free(lnk->menu);
  1585. X      free(lnk);
  1586. X     }
  1587. X     Leave_void
  1588. X}
  1589. X
  1590. X/*
  1591. X * Grab the mouse buttons according to the bindings list.
  1592. X */
  1593. X
  1594. XGrab_Buttons()
  1595. X{
  1596. X     Binding *bptr;
  1597. X     
  1598. X     Entry("Grab_Buttons")
  1599. X     
  1600. X     /*
  1601. X      * don't grab buttons if you don't have to - allow application
  1602. X      * access to buttons unless context includes window.
  1603. X      */
  1604. X     for (bptr = Blist; bptr; bptr = bptr->next) {
  1605. X      if (bptr->context == ROOT)
  1606. X           NeedRootInput = TRUE;
  1607. X      else if (bptr->context & WINDOW) /* We gotta grab on windows */
  1608. X           GrabAll(bptr->mask);
  1609. X     }
  1610. X     Leave_void
  1611. X}
  1612. X
  1613. X/*
  1614. X * Register a grab on all windows in the hierarchy. This is better than
  1615. X * registering a grab on the RootWindow since it leaves button/key chords
  1616. X * available for other contexts.
  1617. X */
  1618. XGrabAll(mask)
  1619. Xunsigned int mask;
  1620. X{
  1621. X     unsigned int junk, nkids;
  1622. X     Window *kiddies;
  1623. X     
  1624. X     Entry("GrabAll")
  1625. X     
  1626. X     if (XQueryTree(dpy, DefaultRootWindow(dpy), &junk, &junk, &kiddies,
  1627. X            &nkids)) {
  1628. X      int i;
  1629. X      
  1630. X      for (i = 0; i < (int)nkids; i++) {
  1631. X           Window transient;
  1632. X           XWindowAttributes xwa;
  1633. X           
  1634. X           /* check to see if it's a popup or something */
  1635. X           XGetWindowAttributes(dpy, kiddies[i], &xwa);
  1636. X           XGetTransientForHint(dpy, kiddies[i], &transient);
  1637. X           if (xwa.class == InputOutput && xwa.map_state == IsViewable &&
  1638. X           xwa.override_redirect == False && transient == None)
  1639. X            Grab(mask, kiddies[i]);
  1640. X      }
  1641. X     }
  1642. X     else
  1643. X      Error("awm: Can't XQueryTree in GrabAll!\n");
  1644. X     Leave_void
  1645. X}
  1646. X
  1647. X/*
  1648. X * Grab a mouse button according to the given mask.
  1649. X */
  1650. XGrab(mask, w)
  1651. Xunsigned int mask;
  1652. XWindow w;
  1653. X{
  1654. X     unsigned int m = LeftMask | MiddleMask | RightMask;
  1655. X     
  1656. X     Entry("Grab")
  1657. X     
  1658. X     switch (mask & m) {
  1659. X     case LeftMask:
  1660. X      XGrabButton(dpy, LeftButton, mask & ModMask, w, TRUE, EVENTMASK,
  1661. X              GrabModeAsync, GrabModeAsync, None, LeftButtonCursor);
  1662. X      break;
  1663. X      
  1664. X     case MiddleMask:
  1665. X      XGrabButton(dpy, MiddleButton, mask & ModMask, w, TRUE, EVENTMASK,
  1666. X              GrabModeAsync, GrabModeAsync, None, MiddleButtonCursor);
  1667. X      break;
  1668. X      
  1669. X     case RightMask:
  1670. X      XGrabButton(dpy, RightButton, mask & ModMask, w, TRUE, EVENTMASK,
  1671. X              GrabModeAsync, GrabModeAsync, None, RightButtonCursor);
  1672. X      break;
  1673. X     }
  1674. X     Leave_void
  1675. X}
  1676. X
  1677. X/*
  1678. X * Restore cursor to normal state.
  1679. X */
  1680. XResetCursor(button)
  1681. Xint button;
  1682. X{
  1683. X     Entry("ResetCursor")
  1684. X     
  1685. X     switch (button) {
  1686. X     case LeftButton:
  1687. X      XChangeActivePointerGrab(dpy, EVENTMASK, LeftButtonCursor,
  1688. X                   CurrentTime);
  1689. X      break;
  1690. X      
  1691. X     case MiddleButton:
  1692. X      XChangeActivePointerGrab(dpy, EVENTMASK, MiddleButtonCursor,
  1693. X                   CurrentTime);
  1694. X      break;
  1695. X      
  1696. X     case RightButton:
  1697. X      XChangeActivePointerGrab(dpy, EVENTMASK, RightButtonCursor,
  1698. X                   CurrentTime);
  1699. X      break;
  1700. X     }
  1701. X     Leave_void
  1702. X}
  1703. X
  1704. X/*
  1705. X * error routine for .awmrc parser
  1706. X */
  1707. Xyyerror(s)
  1708. Xchar*s;
  1709. X{
  1710. X     Entry("yyerror")
  1711. X     
  1712. X     fprintf(stderr, "awm: %s: Line %d: %s\n", sfilename, Lineno, s);
  1713. X     Startup_File_Error = TRUE;
  1714. X     Leave_void
  1715. X}
  1716. X
  1717. X/*
  1718. X * warning routine for .awmrc parser
  1719. X */
  1720. Xyywarn(s)
  1721. Xchar*s;
  1722. X{
  1723. X     Entry("yywarn")
  1724. X     
  1725. X     fprintf(stderr, "awm: Warning: %s: Line %d: %s\n", sfilename, Lineno, s);
  1726. X     Leave_void
  1727. X}
  1728. X
  1729. X/*
  1730. X * Print usage message and quit.
  1731. X */
  1732. XUsage()
  1733. X{
  1734. X     Entry("Usage")
  1735. X     
  1736. X     fputs("Usage: awm [-b] [-i] [-f <file>] [-e <file>] [<host>:<display>]\n\n",
  1737. X       stderr);
  1738. X     fputs("The -b option bypasses system and default bindings\n", stderr);
  1739. X     fputs("The -i option ignores the $HOME/.awmrc file\n", stderr);
  1740. X     fputs("The -f option specifies an alternate startup file\n", stderr);
  1741. X     fputs("The -e option specifies a program/script to exec after startup\n",
  1742. X       stderr);
  1743. X     exit(1);
  1744. X}
  1745. X
  1746. X/*
  1747. X * error handler for X I/O errors
  1748. X */
  1749. X/*ARGSUSED*/
  1750. XXIOError(dsp)
  1751. XDisplay *dsp;
  1752. X{
  1753. X     /* perror("awm"); */
  1754. X     exit(3);
  1755. X}
  1756. END_OF_FILE
  1757. if test 43072 -ne `wc -c <'awm.c'`; then
  1758.     echo shar: \"'awm.c'\" unpacked with wrong size!
  1759. fi
  1760. # end of 'awm.c'
  1761. fi
  1762. if test ! -d 'bitmaps' ; then
  1763.     echo shar: Creating directory \"'bitmaps'\"
  1764.     mkdir 'bitmaps'
  1765. fi
  1766. if test -f 'bitmaps/twm.gray.bm' -a "${1}" != "-c" ; then 
  1767.   echo shar: Will not clobber existing file \"'bitmaps/twm.gray.bm'\"
  1768. else
  1769. echo shar: Extracting \"'bitmaps/twm.gray.bm'\" \(312 characters\)
  1770. sed "s/^X//" >'bitmaps/twm.gray.bm' <<'END_OF_FILE'
  1771. X/* @(#)gray.ic    X10/6.6    11/3/86 */
  1772. X#define gray_width 16
  1773. X#define gray_height 16
  1774. Xstatic char gray_bits[] = {
  1775. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  1776. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  1777. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  1778. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};
  1779. END_OF_FILE
  1780. if test 312 -ne `wc -c <'bitmaps/twm.gray.bm'`; then
  1781.     echo shar: \"'bitmaps/twm.gray.bm'\" unpacked with wrong size!
  1782. fi
  1783. # end of 'bitmaps/twm.gray.bm'
  1784. fi
  1785. if test ! -d 'menus' ; then
  1786.     echo shar: Creating directory \"'menus'\"
  1787.     mkdir 'menus'
  1788. fi
  1789. echo shar: End of archive 1 \(of 12\).
  1790. cp /dev/null ark1isdone
  1791. MISSING=""
  1792. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1793.     if test ! -f ark${I}isdone ; then
  1794.     MISSING="${MISSING} ${I}"
  1795.     fi
  1796. done
  1797. if test "${MISSING}" = "" ; then
  1798.     echo You have unpacked all 12 archives.
  1799.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1800. else
  1801.     echo You still need to unpack the following archives:
  1802.     echo "        " ${MISSING}
  1803. fi
  1804. ##  End of shell archive.
  1805. exit 0
  1806. -- 
  1807. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  1808. Moderator of comp.sources.x
  1809.